﻿using System;
using Bricks.Caching;
using Microsoft.Practices.Unity;

namespace Bricks.Unity.Injecting
{

    /// <summary>
    /// 
    /// </summary>
    public class CachedLifetimeManager : SynchronizedLifetimeManager
    {

        /// <summary>
        /// 
        /// </summary>
        private readonly Func<ICacheFacade> _cacheFacadeAccessor;

        /// <summary>
        /// 
        /// </summary>
        private readonly Guid _key = new Guid();

        /// <summary>
        /// 
        /// </summary>
        /// <param name="cacheFacadeAccessor"></param>
        public CachedLifetimeManager(Func<ICacheFacade> cacheFacadeAccessor)
        {
            if (cacheFacadeAccessor == null)
            {
                throw new ArgumentNullException("cacheFacadeAccessor");
            }
            _cacheFacadeAccessor = cacheFacadeAccessor;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="cacheFacade"></param>
        public CachedLifetimeManager(ICacheFacade cacheFacade) :
            this(() => cacheFacade)
        {
        }

        /// <summary>
        /// 
        /// </summary>
        protected ICacheFacade CacheFacade
        {
            get { return _cacheFacadeAccessor.Invoke(); }
        }

        /// <summary>
        /// 
        /// </summary>
        protected virtual string Key
        {
            get { return _key.ToString(); }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        protected override object SynchronizedGetValue()
        {
            return CacheFacade.Get(Key);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="newValue"></param>
        protected override void SynchronizedSetValue(object newValue)
        {
            CacheFacade.Add(Key, newValue);
        }

        /// <summary>
        ///     
        /// </summary>
        public override void RemoveValue()
        {
            IDisposable disposable = CacheFacade.Get(Key).As<IDisposable>();

            CacheFacade.Remove(Key);

            if (disposable != null)
            {
                disposable.Dispose();
            }
        }
    }
}
